package com.ghp.admin.api;


import com.ghp.common.api.InnerInterfaceInfoService;
import com.ghp.common.exception.BusinessException;
import com.ghp.common.utils.ThrowUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import javax.annotation.Resource;
import java.util.Arrays;

import static com.ghp.common.constants.ErrorMessageConstants.*;
import static com.ghp.common.constants.RedisConstants.INTERFACE_LEFT_NUM_KEY;
import static com.ghp.common.constants.RedisConstants.INTERFACE_PATH_METHOD_KEY;

/**
 * 内部接口服务，提供内部模块之间的接口
 *
 * @author ghp
 */
@DubboService
public class InnerInterfaceInfoServiceImpl implements InnerInterfaceInfoService {

    @Resource
    private RedisTemplate redisTemplate;

    /**
     * Redis脚本，用于判断接口是否存在、同时获取接口调用次数
     */
    private static final DefaultRedisScript<Long> CHECK_SCRIPT;

    static {
        CHECK_SCRIPT = new DefaultRedisScript<>();
        CHECK_SCRIPT.setLocation(new ClassPathResource("lua/check-exist-leftnum.lua"));
        CHECK_SCRIPT.setResultType(Long.class);
    }


    /**
     * 判断接口是否存在同时判断接口是否有剩余调用次数
     *
     * @param path   接口请求地址
     * @param method 接口请求方式
     * @param userId 调用人
     * @return 0-成功 1-接口不存在 2-接口已没有调用次数 null-出错
     */
    @Override
    public Long checkInterfaceExistAndLeftNum(String path, String method, Long userId) {
        // 执行lua脚本判断接口是否存在，接口是否具有剩余调用次数，同时返回接口id
        Long result = null;
        try {
            result = (Long) redisTemplate.execute(
                    CHECK_SCRIPT,
                    Arrays.asList(INTERFACE_PATH_METHOD_KEY, INTERFACE_LEFT_NUM_KEY),
                    path, method, userId
            );
        } catch (Exception e) {
            throw new BusinessException(SCRIPT_EXECUTE_ERROR);
        }
        // 判断接口的状态
        if (result == null || result.intValue() < 0){
            ThrowUtils.throwIf(result == null, SCRIPT_EXECUTE_ERROR);
            throw new BusinessException(result.intValue() == -1 ? INTERFACE_NOT_EXISTS : INTERFACE_NOT_REMAIN);
        }
        return result;
    }
}




